package cn.exrick.xboot.modules.backlogOrFullList.serviceimpl;

import cn.exrick.xboot.common.constant.CommonConstant;
import cn.exrick.xboot.common.formDto.AppBacklogAngle;
import cn.exrick.xboot.common.utils.PageUtil;
import cn.exrick.xboot.common.utils.jiuqi.utils.JiGuangPushUtil;
import cn.exrick.xboot.common.vo.PageVo;
import cn.exrick.xboot.config.pushCode.jPushConfig;
import cn.exrick.xboot.modules.backlogOrFullList.entity.APPBacklogOrFullList;
import cn.exrick.xboot.modules.backlogOrFullList.entity.BacklogOrFullList;
import cn.exrick.xboot.modules.backlogOrFullList.service.IbacklogOrFullListService;
import cn.exrick.xboot.modules.backlogOrFullList.utils.BacklogUtile;
import cn.exrick.xboot.modules.base.entity.Dict;
import cn.exrick.xboot.modules.base.entity.DictData;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.service.DictDataService;
import cn.exrick.xboot.modules.base.service.DictService;
import cn.exrick.xboot.modules.base.service.mybatis.IUserService;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 待办已办列表接口实现
 * @author Exrick
 */
@Slf4j
@Service
@Transactional
public class IbacklogOrFullListServiceImpl extends ServiceImpl<cn.exrick.xboot.modules.backlogOrFullList.dao.mapper.backlogOrFullListMapper, BacklogOrFullList> implements IbacklogOrFullListService {

    @Autowired
    private cn.exrick.xboot.modules.backlogOrFullList.dao.mapper.backlogOrFullListMapper backlogOrFullListMapper;
    @Autowired
    private jPushConfig config;


    @Autowired
    private IbacklogOrFullListService ibacklogOrFullListService;
    @Autowired
    private IUserService iUserService;
    @Autowired
    private DictService dictService;
    @Autowired
    private DictDataService dictDataService;
    @Value("${portal.initBacllog.PageSize}")
    private int initBacllogPageSize;
    @Value("${portal.initBacllog.dictType}")
    private String dictType;


    /**
     * 待办已办列表的条件查询
     * @param page
     * @param backlogOrFullList
     * @return
     */
    @Override
    public IPage<BacklogOrFullList> selectBacklogOrFullListPageVoMap(Page page, @Param("backlogOrFullList") BacklogOrFullList backlogOrFullList ){
        return backlogOrFullListMapper.selectBacklogOrFullListPageVoMap(page,backlogOrFullList);
    }
    /**
     * 20190821
     * njp
     * portal待办已办列表的条件查询(num控制数量)
     * map 为参数
     */
    @Override
    public List<BacklogOrFullList> selectBacklogOrFullListByMap(@Param("map") Map<String,Object> map){
        return backlogOrFullListMapper.selectBacklogOrFullListByMap(map);
    }


    /**
     *查询APP的待办列表
     */
    @Override
    public List<APPBacklogOrFullList> selectBacklogOrFullListAPP(BacklogOrFullList backlogOrFullList){
        return backlogOrFullListMapper.selectBacklogOrFullListAPP(backlogOrFullList);
}
    /**
     * xbw
     * map参数
     */
    @Override
    public Integer UpdateMseeageType(Map<Object, Object> map) {
        return backlogOrFullListMapper.UpdateMseeageType(map);
    }
    /**
     * xbw
     * map参数
     */
    @Override
    public String selectInfoId(Map<Object, Object> mapId) {
        return backlogOrFullListMapper.selectInfoId(mapId);
    }

    /**
     * APP待办已办列表的条件查询
     * @param page
     * @param backlogOrFullList
     * @return
     */
    @Override
    public IPage<BacklogOrFullList> selectBacklogOrFullListPageVoMapApp(Page page, @Param("backlogOrFullList") BacklogOrFullList backlogOrFullList ){
        return backlogOrFullListMapper.selectBacklogOrFullListPageVoMapApp(page,backlogOrFullList);
    }

   /* public Boolean sendBacklogAngleToAPP(  String   username){
        //1.先查询出该用户的待办数量（该方法在待办数量和已办数量发生变化时调用）
        //代办数量
        int num=20;
        Boolean flag=false;
        //开始向APP发送消息
        JPushClient jPushClient = new JPushClient(config.getMasterSecret(),config.getAppKey());
        PushResult pushResultios= JiGuangPushUtil.pushAngleIos(jPushClient,"alias",username, CommonConstant.APP_ALERT,"BacklogAngle",num);
        PushResult pushResultAN= JiGuangPushUtil.pushAngleAndroid(jPushClient,"alias",username, CommonConstant.APP_ALERT,num);
        if (pushResultios.statusCode != 1&&pushResultios.statusCode != 4 &&pushResultAN.statusCode !=1011){
            flag=true;
            log.info("IOS推送角标成功"+username);
        }
        if(pushResultAN.statusCode != 1&&pushResultAN.statusCode != 4 && pushResultAN.statusCode !=1011){
            flag=true;
            log.info("安卓推送角标成功"+username);
        }
        if(pushResultios.statusCode == 1&&pushResultios.statusCode == 4&&pushResultAN.statusCode == 1&&pushResultAN.statusCode == 4&&pushResultAN.statusCode !=1011) {
            log.info("推送角标失败"+username);
            flag=false;
        }
        return flag;
    }*/



    /**
     * 向APP中推送待办角标
     * 数量
     * username  用户名 eg：
     * @param  num 待办数量（角标数量）
     * @return
     */
    @Override
    public Boolean sendBacklogAngleToAPPIos(String username,Integer num,String alert){
        Boolean flag=false;
        //向ios推送待办的总数

        JPushClient jPushClient = new JPushClient(config.getMasterSecret(),config.getAppKey());
        PushResult pushResultios= JiGuangPushUtil.pushAngleIos(jPushClient,"alias",username,alert ,"BacklogAngle",num);
        if(pushResultios.statusCode == 1&&pushResultios.statusCode == 4&&pushResultios.statusCode ==1011) {
            log.info("推送角标失败"+username);
            flag=false;
            return flag;
        }
        log.info("IOS推送角标成功"+username);
        return flag;
    }

    /**
     * 向APP中推送待办角标
     * 数量
     * username  用户名 eg：admin
     * @return
     */
    @Override
    public Boolean sendBacklogAngleToAPPAndroid(    String   username,Integer num,String alert){
        Boolean flag=false;
        JPushClient jPushClient = new JPushClient(config.getMasterSecret(),config.getAppKey());
        PushResult pushResultAN= JiGuangPushUtil.pushAngleAndroid(jPushClient,"alias",username, alert,num);
        if(pushResultAN.statusCode == 1&&pushResultAN.statusCode == 4&&pushResultAN.statusCode ==1011) {
            log.info("安卓推送角标失败"+username);
            flag=false;
            return flag;
        }
        log.info("安卓推送角标成功"+username+"num="+num);
        return flag;
    }

    /**
     * 向APP中推送待办角标(使用自定义消息的方法推送角标)
     * 数量
     * @param  username  用户名 eg：admin
     * @param num 待办总数
     * @return
     */
    @Override
    public Boolean sendBacklogAngleAllToAPPAndroid(String  username,Integer num){
        Boolean flag=false;
        JPushClient jPushClient = new JPushClient(config.getMasterSecret(),config.getAppKey());
        //todo 调用创建自定义消息体的方法
        AppBacklogAngle appBacklogAngle=new AppBacklogAngle(username,num);
        Map<String, String> map = IbacklogOrFullListServiceImpl.getAppMap(appBacklogAngle);
        PushResult pushResultAN= JiGuangPushUtil.pushAngleAndroid(jPushClient,username,map);
        if(pushResultAN.statusCode == 1&&pushResultAN.statusCode == 4&&pushResultAN.statusCode ==1011) {
            log.info("安卓推送角标总数失败"+username);
            flag=false;
            return flag;
        }
        log.info("安卓推送角标总数成功"+username);
        return flag;
    }


    /**
     * njp
     * 查询当前用户的待办数量
     * @param username 账号
     * @return
     */
    @Override
    public Integer selectBacklogAngleNum(  String username ){
        return   backlogOrFullListMapper.selectBacklogAngleNum(username);
    }

    /**
     * add njp 20200427
     * 通过messageId删除待办已办数据
     * @return
     */
    @Override
    public void deleteBacklogByMessageID(  String messageId ){
        backlogOrFullListMapper.deleteBacklogByMessageID(messageId);
    }


    /**
     * 创建自定义消息体的方法
     * @param
     * @return
     */
    public static Map<String,String> getAppMap( AppBacklogAngle appBacklogAngle) {
        Map map=new HashMap() ;
        map.put("body" , JSONObject.toJSONString(appBacklogAngle));//对象数据
        log.info("json"+JSONObject.toJSONString(appBacklogAngle, SerializerFeature.WriteDateUseDateFormat));//格式化时间
        //map.put("admin" ,CommonConstant.PARAM_USERNAME);//管理员账号
        map.put("RequestType" ,"AngleMinus");//推送业务数据类型
        return  map;
    }

    /**
     * 解析批量的待办数据
     * @param jsonObject
     */
    @Override
    public void parseBacklogsJson(JSONObject jsonObject){
        try {
            JSONObject jsonInfo = jsonObject;
            JSONArray arr = jsonInfo.getJSONArray("datas");
            //JSONObject Data = JSON.parseObject(jsonInfo.getString("data"));//取出json数据中的data
            //JSONArray jsonArray = jsonInfo.getJSONArray("data");
            log.info("接受数组长度"+arr.size());
            for (int i = 0; i < arr.size(); i++) {
                JSONObject Data = arr.getJSONObject(i);
                BacklogOrFullList backlogOrFullList = new BacklogOrFullList();
                String titlt = Data.getString("title");
                String messageID = Data.getString("messageID");
                String infoId = Data.getString("doID");
                String moduleName = Data.getString("sender");
                String userCode = Data.getString("usercode");
                String code = Data.getString("changingtype");
                String createtime = Data.getString("createtime");
                Date createdate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(createtime);

                backlogOrFullList.setMessageId(messageID);
                backlogOrFullList.setTitle(titlt);
                backlogOrFullList.setInfoId(infoId);
                backlogOrFullList.setCode(code);
                backlogOrFullList.setModuleName(moduleName);
                backlogOrFullList.setUserCode(userCode);
                backlogOrFullList.setCreateTime(createdate);

           /* Map<Object, Object> mapId = new HashMap<>();
            mapId.put("userCode", userCode);
            mapId.put("messageID", messageID);
            String DBMessageID = ibacklogOrFullListService.selectInfoId(mapId);*/

                //njp TODO 在添加待办时判断messageID消息是否重复如果重复按照修改操作将本地的删除然后新增一条

                //njp modify 2020027 done代表待办变已办 begin
                if ("done".equals(code)) {
                    //njp modify 2020027 done代表待办变已办 end
                    Map<String, Object> map = new HashMap<>();
                    map.put("user_code", userCode);
                    map.put("message_id", messageID);
                    //约定大于配置（约定待办已办的messageid是全局唯一的）
                    map.put("code","todo");
                    List<BacklogOrFullList> backlogOrFullLists=new ArrayList<>(listByMap(map));
                    if(backlogOrFullLists.size()>0){
                        //做修改操作前提
                        backlogOrFullList.setId(backlogOrFullLists.get(0).getId());
                    }
                    //njp add 20200506 避免多次存储同一条待办数据，先判断该条数据是否存在 end
                    //njp  modify 2020027 todo代表待办（新增待办）
                    backlogOrFullList.setUpdateTime(createdate);
                    saveOrUpdate(backlogOrFullList);

                } else if("todo".equals(code)){
                    //njp add 20200506 避免多次存储同一条待办数据，先判断该条数据是否存在 begin
                    Map<String, Object> mapId = new HashMap<>();
                    mapId.put("user_code", userCode);
                    mapId.put("message_id", messageID);
                    mapId.put("code","todo");
                    //String DBMessageID = ibacklogOrFullListService.selectInfoId(mapId);
                    //todo
                    List<BacklogOrFullList> backlogOrFullLists=new ArrayList<>(listByMap(mapId));
                    if(backlogOrFullLists.size()>0){
                        //做修改操作
                        backlogOrFullList.setId(backlogOrFullLists.get(0).getId());
                    }
                    //njp add 20200506 避免多次存储同一条待办数据，先判断该条数据是否存在 end
                    //njp  modify 2020027 todo代表待办（新增待办）
                    saveOrUpdate(backlogOrFullList);
                    log.info("转换成待办实体数据:" + backlogOrFullList.toString());
                    //  njp add  新增待办后向 app推送待办数量（ios推送待办总数，安卓推送新增的数量）
                }else if ("delete".equals(code)){
                    // njp modify 2020027   delete代表删除待办（删除待办待办）begin
                    // 1.根据数据messageID和usercode删除portal中的待办（该删除操作是为了配合流程中的取回操作等）
                    Map<String,Object> map=new HashMap<>();
                    map.put("user_code",userCode);
                    map.put("message_id",messageID);
                    //njp addt 添加只删除待办数据的逻辑
                    map.put("code","todo");
                    //ibacklogOrFullListService.deleteBacklogByMessageID(messageID);
                    removeByMap(map);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     *根据用户删除待办
     * @param userId
     */
    @Override
    public void deleteBacklogByUser(@Param("userId") String userId){
         backlogOrFullListMapper.deleteBacklogByUser(userId);
    }

    /**
     * 根据users批量删除
     * @param userlist
     */
    @Override
    public Boolean deleteBacklogByUsers( List<User> userlist){
        return backlogOrFullListMapper.deleteBacklogByUsers(userlist);
    }
    /**
     * 初始化待办数据
     * @param userlist
     * @param urls
     * @return
     */
    @Override
    public boolean initBacllog(List<User> userlist, List<DictData> urls){
        boolean isok=false;
        String url="";
        try {

        RestTemplate restTemplate=new RestTemplate();
        JSONObject jsonObject = new BacklogUtile().javaToJSON(userlist);
        for (int i = 0; i < urls.size(); i++) {
             url=urls.get(i).getValue();
             log.info("请求地址:"+url+",初始化待办数据的请求报文datas:"+jsonObject.toString());
            JSONObject json = restTemplate.postForEntity(url, jsonObject, JSONObject.class).getBody();
            log.info("待办初始化接'"+url+"'口返回报文:"+json.toJSONString());
            Boolean success = json.getBoolean("success");
            String message = json.getString("message");
            String code = json.getString("code");
            if(success==null?false:success){
                this.deleteBacklogByUsers(userlist);
                this.parseBacklogsJson(json);
            }
        }
        }catch (ResourceAccessException rae){
            isok=false;
            log.error("调用初始化接口'"+url+"'失败");
            //rae.printStackTrace();
            log.error(rae.getMessage());
        }catch (Exception e){
            log.error("调用初始化接口'"+url+"未知错误");
            log.error(e.getMessage());
        }
        return isok;
    }

    /**
     * njp
     * 待办初始化（通过拉取数据的方式）
     * （准备访问参数数据）
     */
    @Override
    public void backlogInitByCall(){
        // 1.查询user
        int pageNumber=1;
        PageVo page=new PageVo(pageNumber,initBacllogPageSize);
        IPage<User> userByPage = iUserService.getUserByPage(PageUtil.initMpPage(page));
        log.info("userByPage总页数："+userByPage.getPages());
        // 2.查询三方服务的初始化接口数据
        Dict byType = dictService.findByType(dictType);
        log.info("查询三方服务的初始化接口数据结果："+byType.toString());
        List<DictData> urls = dictDataService.findByDictIdAndStatusOrderBySortOrder(byType.getId(), CommonConstant.STATUS_NORMAL);
        log.info("backlogInitByCall待办初始化url有："+urls.toString());
        // 3.通过userlist进行初始化  4.根据总页数进行初始化
        for (int i = 0; i < userByPage.getPages(); i++,pageNumber++) {
            log.info("开始拉取第"+pageNumber+"页待办数据");
            PageVo userPage=new PageVo(pageNumber,initBacllogPageSize);
            IPage<User> userPages = iUserService.getUserByPage(PageUtil.initMpPage(userPage));
            List<User> userlist = userPages.getRecords();
            boolean b = ibacklogOrFullListService.initBacllog(userlist, urls);
        }
    }

}
